#include "cbuffer.h"
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

CBuffer::CBuffer(int size){
    m_buffer = new char[size];
    m_buffer_size = size;
}

CBuffer::~CBuffer(){
    if(m_buffer){
        delete[] m_buffer;
        m_buffer = nullptr;
    }
}

bool CBuffer::push(const char * data, int size){
    if(m_buffer_data_size + size > m_buffer_size){
        return false;
    }
    memcpy(m_buffer + m_buffer_data_size, data, size);
    m_buffer_data_size += size;
    return true;
}

bool CBuffer::push(std::string & str){
    return push(str.c_str(), str.size());
}

bool CBuffer::push(String & str){
    return push(str.c_str(), str.length());
}

void CBuffer::pop(int size){
    int remain_size = m_buffer_data_size - size;
    if(remain_size <= 0){
        m_buffer_data_size = 0;
        return;
    }
    memcpy(m_buffer, m_buffer + size, remain_size);
	m_buffer_data_size = remain_size;
}

void CBuffer::clear(){
    m_buffer_data_size = 0;
}

int CBuffer::operator<<(int sockfd){
    int remain_size = m_buffer_size - m_buffer_data_size;
    if(remain_size <= 0){
        return 0;
    }
    int len = read(sockfd, m_buffer + m_buffer_data_size, remain_size);
    if(len <= 0){
        return 0;
    }
    m_buffer_data_size += len;
    return len;
}

int CBuffer::operator>>(int sockfd){
    if(m_buffer_data_size <= 0 || sockfd < 0){
        return 0;
    }
    int ret = write(sockfd, m_buffer, m_buffer_data_size);
    if(ret <= 0){
        return 0;
    }else if(ret == m_buffer_data_size){
        m_buffer_data_size = 0;
    }else{
        m_buffer_data_size -= ret;
        memcpy(m_buffer, m_buffer + ret, m_buffer_data_size);
    }
    return ret;
}

bool CBuffer::operator<<(std::string & str){
    return push(str.c_str(), str.size());
}

bool CBuffer::operator<<(String & str){
    return push(str.c_str(), str.length());
}
